package tech.lq0.dreamaticvoyage.datagen;

import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.common.Tags;
import net.minecraftforge.common.data.BlockTagsProvider;
import net.minecraftforge.common.data.ExistingFileHelper;
import tech.lq0.dreamaticvoyage.Utils;
import tech.lq0.dreamaticvoyage.init.BlockRegistry;
import tech.lq0.dreamaticvoyage.tools.ModTags;

import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;

public class ModBlockTagProvider extends BlockTagsProvider {
    public ModBlockTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, @Nullable ExistingFileHelper existingFileHelper) {
        super(output, lookupProvider, Utils.MOD_ID, existingFileHelper);
    }

    @Override
    protected void addTags(HolderLookup.Provider pProvider) {
        this.tag(BlockTags.MINEABLE_WITH_PICKAXE)
                .add(BlockRegistry.RED_AHOGE_BLOCK.get(), BlockRegistry.WHITE_AHOGE_BLOCK.get(), BlockRegistry.COMMUNICATION_TABLE.get(),
                        BlockRegistry.PORCELAIN_THRONE.get(), BlockRegistry.POINTS_STORE.get(), BlockRegistry.BLUE_SANDSTONE.get(),
                        BlockRegistry.BLUE_SANDSTONE_SLAB.get(), BlockRegistry.CUT_BLUE_SANDSTONE.get(), BlockRegistry.CUT_BLUE_SANDSTONE_SLAB.get(),
                        BlockRegistry.SMOOTH_BLUE_SANDSTONE.get(), BlockRegistry.SMOOTH_BLUE_SANDSTONE_SLAB.get(), BlockRegistry.SMOOTH_BLUE_SANDSTONE_STAIRS.get(),
                        BlockRegistry.BLUE_SANDSTONE_STAIRS.get(), BlockRegistry.BLUE_SANDSTONE_WALL.get(), BlockRegistry.CHISELED_BLUE_SANDSTONE.get(),
                        BlockRegistry.HARDEN_CRYSTAL_BLOCK.get(), BlockRegistry.PURIFIED_CRYSTAL_BLOCK.get(), BlockRegistry.CHARGED_CRYSTAL_BLOCK.get(),
                        BlockRegistry.ANTI_INGOT_BLOCK.get(), BlockRegistry.ROCK_STATUE.get(), BlockRegistry.PHANTASMAL_VOYAGER.get(),
                        BlockRegistry.CRYSTAL_POPPER.get(), BlockRegistry.GACHI_INGOT_BLOCK.get(), BlockRegistry.CRYSTAL_PURIFIER.get(),
                        BlockRegistry.CRYSTAL_CUTTER.get())
                .addTag(ModTags.Blocks.FUKAMIZU_MACHINE)
                .addTag(ModTags.Blocks.FUKAMIZU_BREAD);
        this.tag(BlockTags.MINEABLE_WITH_SHOVEL).add(BlockRegistry.BLUE_SAND.get());
        this.tag(BlockTags.MINEABLE_WITH_AXE).add(BlockRegistry.UNI_MILLET_BLOCK.get(),
                BlockRegistry.HARANO_LOG.get(), BlockRegistry.HARANO_WOOD.get(), BlockRegistry.HARANO_SLAB.get(), BlockRegistry.HARANO_PLANKS.get(),
                BlockRegistry.HARANO_STAIRS.get(), BlockRegistry.STRIPPED_HARANO_LOG.get(), BlockRegistry.STRIPPED_HARANO_WOOD.get(),
                BlockRegistry.HARANO_FENCE.get(), BlockRegistry.HARANO_FENCE_GATE.get(), BlockRegistry.HARANO_PRESSURE_PLATE.get(),
                BlockRegistry.HARANO_DOOR.get(), BlockRegistry.HARANO_TRAPDOOR.get(), BlockRegistry.HARANO_BUTTON.get(),
                BlockRegistry.FUKAMIZU_PLUM_LOG.get(), BlockRegistry.FUKAMIZU_PLUM_PLANKS.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_LOG.get(),
                BlockRegistry.FUKAMIZU_PLUM_WOOD.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_WOOD.get(), BlockRegistry.FUKAMIZU_PLUM_SLAB.get(),
                BlockRegistry.FUKAMIZU_PLUM_STAIRS.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE_GATE.get(),
                BlockRegistry.FUKAMIZU_PLUM_PRESSURE_PLATE.get(), BlockRegistry.FUKAMIZU_PLUM_BUTTON.get(),
                BlockRegistry.FUKAMIZU_PLUM_DOOR.get(), BlockRegistry.FUKAMIZU_PLUM_TRAPDOOR.get()
        );
        this.tag(BlockTags.MINEABLE_WITH_HOE).add(BlockRegistry.HARANO_LEAVES.get(), BlockRegistry.UNI_MILLET_BLOCK.get(), BlockRegistry.FUKAMIZU_PLUM_LEAVES.get());

        this.tag(BlockTags.NEEDS_STONE_TOOL).add(BlockRegistry.RED_AHOGE_BLOCK.get(), BlockRegistry.WHITE_AHOGE_BLOCK.get(),
                BlockRegistry.HARDEN_CRYSTAL_BLOCK.get());
        this.tag(BlockTags.NEEDS_IRON_TOOL).add(BlockRegistry.PURIFIED_CRYSTAL_BLOCK.get(), BlockRegistry.CHARGED_CRYSTAL_BLOCK.get());
        this.tag(BlockTags.NEEDS_DIAMOND_TOOL).add(BlockRegistry.ANTI_INGOT_BLOCK.get(), BlockRegistry.GACHI_INGOT_BLOCK.get());

        this.tag(BlockTags.BEE_GROWABLES).add(BlockRegistry.UNI_MILLET_BLOCK.get());
        this.tag(BlockTags.CROPS).add(BlockRegistry.UNI_MILLET_BLOCK.get());
        this.tag(BlockTags.SAND).add(BlockRegistry.BLUE_SAND.get());
        this.tag(Tags.Blocks.SANDSTONE)
                .add(BlockRegistry.BLUE_SANDSTONE.get(), BlockRegistry.CUT_BLUE_SANDSTONE.get(),
                        BlockRegistry.SMOOTH_BLUE_SANDSTONE.get(), BlockRegistry.CHISELED_BLUE_SANDSTONE.get());
        this.tag(BlockTags.LOGS)
                .add(BlockRegistry.HARANO_LOG.get(), BlockRegistry.HARANO_WOOD.get(), BlockRegistry.STRIPPED_HARANO_LOG.get(), BlockRegistry.STRIPPED_HARANO_WOOD.get(),
                        BlockRegistry.FUKAMIZU_PLUM_LOG.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_LOG.get(), BlockRegistry.FUKAMIZU_PLUM_WOOD.get(),
                        BlockRegistry.STRIPPED_FUKAMIZU_PLUM_WOOD.get());
        this.tag(BlockTags.LOGS_THAT_BURN)
                .add(BlockRegistry.HARANO_LOG.get(), BlockRegistry.HARANO_WOOD.get(), BlockRegistry.STRIPPED_HARANO_LOG.get(), BlockRegistry.STRIPPED_HARANO_WOOD.get(),
                        BlockRegistry.FUKAMIZU_PLUM_LOG.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_LOG.get(), BlockRegistry.FUKAMIZU_PLUM_WOOD.get(),
                        BlockRegistry.STRIPPED_FUKAMIZU_PLUM_WOOD.get());
        this.tag(BlockTags.WALLS).add(BlockRegistry.BLUE_SANDSTONE_WALL.get());
        this.tag(BlockTags.SWORD_EFFICIENT).add(BlockRegistry.UNI_MILLET_BLOCK.get());
        this.tag(BlockTags.SLABS)
                .add(BlockRegistry.BLUE_SANDSTONE_SLAB.get(), BlockRegistry.SMOOTH_BLUE_SANDSTONE_SLAB.get(),
                        BlockRegistry.CUT_BLUE_SANDSTONE_SLAB.get(), BlockRegistry.HARANO_SLAB.get(), BlockRegistry.FUKAMIZU_PLUM_SLAB.get());
        this.tag(BlockTags.SMELTS_TO_GLASS).add(BlockRegistry.BLUE_SAND.get());
        this.tag(BlockTags.STAIRS)
                .add(BlockRegistry.BLUE_SANDSTONE_STAIRS.get(), BlockRegistry.SMOOTH_BLUE_SANDSTONE_STAIRS.get(),
                        BlockRegistry.HARANO_STAIRS.get(), BlockRegistry.FUKAMIZU_PLUM_STAIRS.get());
        this.tag(BlockTags.PLANKS).add(BlockRegistry.HARANO_PLANKS.get(), BlockRegistry.FUKAMIZU_PLUM_PLANKS.get());
        this.tag(BlockTags.FENCES).add(BlockRegistry.HARANO_FENCE.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE.get());
        this.tag(BlockTags.WOODEN_FENCES).add(BlockRegistry.HARANO_FENCE.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE.get());
        this.tag(BlockTags.FENCE_GATES).add(BlockRegistry.HARANO_FENCE_GATE.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE_GATE.get());
        this.tag(BlockTags.PRESSURE_PLATES).add(BlockRegistry.HARANO_PRESSURE_PLATE.get(), BlockRegistry.FUKAMIZU_PLUM_PRESSURE_PLATE.get());
        this.tag(BlockTags.WOODEN_PRESSURE_PLATES).add(BlockRegistry.HARANO_PRESSURE_PLATE.get(), BlockRegistry.FUKAMIZU_PLUM_PRESSURE_PLATE.get());
        this.tag(BlockTags.LEAVES).add(BlockRegistry.HARANO_LEAVES.get(), BlockRegistry.FUKAMIZU_PLUM_LEAVES.get());
        this.tag(Tags.Blocks.SAND).add(BlockRegistry.BLUE_SAND.get());
        this.tag(BlockTags.DOORS).add(BlockRegistry.HARANO_DOOR.get(), BlockRegistry.FUKAMIZU_PLUM_DOOR.get());
        this.tag(BlockTags.WOODEN_DOORS).add(BlockRegistry.HARANO_DOOR.get(), BlockRegistry.FUKAMIZU_PLUM_DOOR.get());
        this.tag(BlockTags.TRAPDOORS).add(BlockRegistry.HARANO_TRAPDOOR.get(), BlockRegistry.FUKAMIZU_PLUM_TRAPDOOR.get());
        this.tag(BlockTags.WOODEN_TRAPDOORS).add(BlockRegistry.HARANO_TRAPDOOR.get(), BlockRegistry.FUKAMIZU_PLUM_TRAPDOOR.get());
        this.tag(BlockTags.BUTTONS).add(BlockRegistry.HARANO_BUTTON.get(), BlockRegistry.FUKAMIZU_PLUM_BUTTON.get());
        this.tag(BlockTags.WOODEN_BUTTONS).add(BlockRegistry.HARANO_BUTTON.get(), BlockRegistry.FUKAMIZU_PLUM_BUTTON.get());
        this.tag(BlockTags.WITHER_IMMUNE).add(BlockRegistry.ANTI_INGOT_BLOCK.get(), BlockRegistry.GACHI_INGOT_BLOCK.get())
                .addTag(ModTags.Blocks.FUKAMIZU_BREAD);

        this.tag(forgeTag("stripped_logs")).add(BlockRegistry.STRIPPED_HARANO_LOG.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_LOG.get());
        this.tag(forgeTag("stripped_wood")).add(BlockRegistry.STRIPPED_HARANO_WOOD.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_WOOD.get());

        this.tag(ModTags.Blocks.FUKAMIZU_MACHINE).add(BlockRegistry.FUKAMIZU_COMPRESSOR.get(), BlockRegistry.FUKAMIZU_CRUSHER.get(),
                BlockRegistry.FUKAMIZU_PYLON.get(), BlockRegistry.LIGHT_BREAD_ENERGY_BLOCK.get(), BlockRegistry.FUKAMIZU_BREAD_FURNACE.get(),
                BlockRegistry.FUKAMIZU_REACTION_CHAMBER.get(), BlockRegistry.FUKAMIZU_MACHINE_CASING.get(), BlockRegistry.REINFORCED_FUKAMIZU_MACHINE_CASING.get(),
                BlockRegistry.FUKAMIZU_TURBINE_ENGINE.get(), BlockRegistry.UMISU_PYLON.get(), BlockRegistry.MOLTEN_BREAD_ENERGY_BLOCK.get(),
                BlockRegistry.FUKAMIZU_PUNCH.get(), BlockRegistry.FUKAMIZU_FERMENTER.get(), BlockRegistry.FUKAMIZU_EXTRACTION_MACHINE.get(),
                BlockRegistry.FUKAMIZU_BOOSTER.get());
        this.tag(ModTags.Blocks.FUKAMIZU_BREAD).add(BlockRegistry.FUKAMIZU_BREAD_BLOCK.get(), BlockRegistry.FUKAMIZU_BREAD_BRICKS.get(),
                BlockRegistry.HQSS_BREAD_BRICKS.get());

        this.tag(ModTags.Blocks.HARANO).add(BlockRegistry.HARANO_LOG.get(), BlockRegistry.HARANO_WOOD.get(), BlockRegistry.HARANO_SLAB.get(),
                BlockRegistry.HARANO_PLANKS.get(), BlockRegistry.HARANO_STAIRS.get(), BlockRegistry.STRIPPED_HARANO_LOG.get(),
                BlockRegistry.STRIPPED_HARANO_WOOD.get(), BlockRegistry.HARANO_FENCE.get(), BlockRegistry.HARANO_FENCE_GATE.get(),
                BlockRegistry.HARANO_PRESSURE_PLATE.get(), BlockRegistry.HARANO_DOOR.get(), BlockRegistry.HARANO_TRAPDOOR.get(),
                BlockRegistry.HARANO_BUTTON.get(), BlockRegistry.HARANO_LEAVES.get(), BlockRegistry.HARANO_SAPLING.get());
        this.tag(ModTags.Blocks.FUKAMIZU_PLUM).add(BlockRegistry.FUKAMIZU_PLUM_LOG.get(), BlockRegistry.FUKAMIZU_PLUM_WOOD.get(), BlockRegistry.FUKAMIZU_PLUM_SLAB.get(),
                BlockRegistry.FUKAMIZU_PLUM_PLANKS.get(), BlockRegistry.FUKAMIZU_PLUM_STAIRS.get(), BlockRegistry.STRIPPED_FUKAMIZU_PLUM_LOG.get(),
                BlockRegistry.STRIPPED_FUKAMIZU_PLUM_WOOD.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE.get(), BlockRegistry.FUKAMIZU_PLUM_FENCE_GATE.get(),
                BlockRegistry.FUKAMIZU_PLUM_PRESSURE_PLATE.get(),
                BlockRegistry.FUKAMIZU_PLUM_DOOR.get(), BlockRegistry.FUKAMIZU_PLUM_TRAPDOOR.get(),
                BlockRegistry.FUKAMIZU_PLUM_BUTTON.get(), BlockRegistry.FUKAMIZU_PLUM_LEAVES.get(), BlockRegistry.FUKAMIZU_PLUM_SAPLING.get());

        this.tag(ModTags.Blocks.ELECTRICAL_BLOCKS).addTag(BlockTags.BUTTONS)
                .add(Blocks.LEVER, Blocks.REPEATER, Blocks.COMPARATOR, Blocks.REDSTONE_WIRE)
                .addOptional(loc("create", "analog_lever"))
                .addOptional(loc("create", "pulse_repeater"))
                .addOptional(loc("create", "redstone_link"))
                .addOptional(loc("create", "powered_latch"))
                .addOptional(loc("create", "powered_toggle_latch"))
                .addOptional(loc("create", "pulse_extender"));
    }

    private static TagKey<Block> forgeTag(String name) {
        return BlockTags.create(loc("forge", name));
    }

    private static ResourceLocation loc(String modId, String path) {
        return new ResourceLocation(modId, path);
    }
}
